#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <omp.h>
#include "blowfish.h"

int main(int argc, char* argv[])
{
	FILE *keyfile, *infile, *outfile;
	uint32_t *key;
	uint64_t *file, *dec_file;
	struct stat buf;
	int i;
	int file_size, key_size, blocks, samples;
	char* key_str,*outfile_name;
	char rem_bytes;
	double start_time, total_time = 0;
	
	if(argc != 3)
	{
		printf("Usage: ./bfdecrypt <filename> <keyfile>\n");
		exit(1);
	}
	
	infile = fopen(argv[1], "rb");
	
	if(infile == NULL)
	{
		printf("Could not open input file %s.\n",argv[1]);
		exit(1);
	}
	
	keyfile = fopen(argv[2], "r");
	
	if(keyfile == NULL)
	{
		printf("Could not open keyfile.\n");
		exit(1);
	}
	
	outfile_name = (char*)malloc(strlen(argv[1])+5);
	strcpy(outfile_name,argv[1]);
	strcat(outfile_name,".dec");
	
	outfile = fopen(outfile_name,"wb");
	free(outfile_name);
	
	if(outfile == NULL)
	{
		printf("Could not open output file %s.\n",outfile_name);
		exit(1);
	}
	
	fstat(fileno(keyfile), &buf);
	
	file_size = buf.st_size;
	
	blocks = file_size/8;
	
	key_size = blocks*32;
	
	//printf("Key file size: %d\nKey size: %d\nBlocks: %d\n",file_size,key_size,blocks);
	
	key_str = (char*)calloc(17,sizeof(char));
	
	key = (uint32_t*)malloc(blocks*sizeof(uint32_t));
	
	for(i = 0; i < 8*blocks; i+=8)
	{
		fread((void*)(key_str),1,8,keyfile);
		//printf("%d: %s\n",i/8,key_str);
		key[i/8] = (uint32_t)strtoul(key_str,NULL,16);
	}
	
	/*for(i = 0; i < blocks; i++)
	{
		printf("%#lx\n",key[i]);
	}*/
	
	fstat(fileno(infile), &buf);
	
	file_size = buf.st_size;
	
	//printf("Infile size: %d\n",file_size);
	
	//Get number of padding bytes
	fseek(infile,-1,SEEK_END);
	fread((void*)(&rem_bytes),1,1,infile);
	rewind(infile);
	
	file = (uint64_t*)calloc(file_size/sizeof(uint64_t),sizeof(uint64_t));
	dec_file = (uint64_t*)calloc(file_size/sizeof(uint64_t),sizeof(uint64_t));
	
	fread((void*)file,1,file_size,infile);
	for(samples = 0; samples < NUM_SAMPLES; samples++)
	{
		start_time = omp_get_wtime();
		gen_subkeys(key,key_size);
		for(i = 0; i < file_size/8; i++)
		{
			dec_file[i] = blowfish_dec(file+i);
		}
		total_time += omp_get_wtime() - start_time;
	}
	fwrite((void*)dec_file,1,file_size-rem_bytes-1,outfile);
	printf("1,%.9f\n",total_time/(double)(NUM_SAMPLES));
	
	fclose(keyfile);
	fclose(infile);
	fclose(outfile);
	return 0;
}
